package com.zhihao.zhihaopicturebackend.model.enums;

import cn.hutool.core.util.ObjUtil;
import lombok.Getter;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Jackson
 * @create 2024/12/20 15:24
 * @description 用户角色枚举类(哈希表缓存优化)
 */
@Getter
public enum UserRoleEnum {

    USER("用户", "user"),
    ADMIN("管理员", "admin");

    private final String text;

    private final String value;

    UserRoleEnum(String text, String value) {
        this.text = text;
        this.value = value;
    }

    /*
        枚举类和枚举实例的生命周期
            类加载：
                枚举类在JVM中是通过类加载器进行加载的。当JVM首次遇到对枚举类的引用时，会加载该枚举类，并且在加载过程中初始化所有枚举常量。
            枚举实例的创建：
                枚举实例是在类加载时通过静态初始化块创建的。这意味着在程序运行期间，所有的枚举实例都会被创建并保存在内存中。
        枚举实例的存储
            静态变量和方法区：
                枚举实例是通过静态变量保存的，这些静态变量存储在方法区中（在Java 8及以后的版本中称为元空间，Metaspace）。
                静态变量与类的生命周期绑定，只要类在JVM中存在，静态变量就会一直存在，因此枚举实例不会被回收。
            堆区存储：
                枚举实例在堆区中存储，并且由方法区中的静态引用持有其引用。由于这些引用始终存在，枚举实例就始终是可达的，不会被垃圾回收器回收。
    */
    /*
        静态 HashMap 存储枚举实例
        1. 枚举类中的每个Enum实例是在 ’类初始化阶段‘ 通过调用构造函数创建(堆区)
        2. 静态变量绑定类对象,JVM进行‘链接阶段’的时候为静态变量分配内存，并赋默认值
        3. ’静态代码块‘：执行代码，将所有的Enum实例都存储于hashmap中
        4. getEnumByValue()：此时其他代码每次调用get都直接从hashmap中进行‘原子性查询’，事件复杂度为O(1)
               常规的xxxEntity.values()遍历查询，事件复杂度为O(n);
        上述思路仅适合于‘枚举类的Enum常量较多/很多；如果很少的Enum常量的话，遍历查询性能与hashmap查询性能不差的’
     */
    private static final Map<String, UserRoleEnum> VALUE_MAP = new HashMap<>();

    // 静态块初始化 HashMap
    static {
        for (UserRoleEnum role : UserRoleEnum.values()) {
            VALUE_MAP.put(role.value, role);
        }
    }

    /**
     *
     * @param value 枚举值的value
     * @return 枚举值
     */
    public static UserRoleEnum getEnumByValue(String value) {
        if (ObjUtil.isEmpty(value)) {
            return null;
        }
        return VALUE_MAP.get(value);
    }

//    /**
//     * 根据 value 获取枚举(枚举实体少的时候直接使用遍历查询即可)
//     *
//     * @param value 枚举值的value
//     * @return 枚举值
//     */
//    public static UserRoleEnum getEnumByValue(String value) {
//        if (ObjUtil.isEmpty(value)) {
//            return null;
//        }
//        for (UserRoleEnum anEnum : UserRoleEnum.values()) {
//            if (anEnum.value.equals(value)) {
//                return anEnum;
//            }
//        }
//        return null;
//    }
}
